﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WJP.Domain
{
    /// <summary>
    /// 所有实体集合类的基类
    /// </summary>
    [Serializable]
    public abstract class EntityList : SimpleCollection, IEntityList, IDirtyAware
    {
        #region 属性
        
        /// <summary>
        /// 本列表中已经被移除的所有对象
        /// </summary>
        public IList<Entity> DeletedList { get; private set; }

        #endregion

        #region Interface

        /// <summary>
        /// 获取或设置指定索引处的元素
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public new Entity this[int index]
        {
            get
            {
                return (Entity)Items[index];
            }
            set
            {
                SetItem(index, value);
            }
        }

        /// <summary>
        /// 返回当前列表是否需要保存
        /// </summary>
        public bool IsDirty
        {
            get
            {
                for(int index = 0; index < Count; ++index)
                {
                    if (this[index].IsDirty)
                        return true;
                }
                return DeletedList != null && DeletedList.Count > 0;
            }
        }

        /// <summary>
        /// 将当前列表中所有的组合对象树都标记为未变更状态
        /// </summary>
        public void MarkSaved()
        {
            DeletedList = null;
            foreach(Entity entity in this)
            {
                if (entity.IsDirty)
                    entity.MarkSaved();
            }
        }

        #endregion

        #region Override

        /// <summary>
        /// 清空所有项
        /// </summary>
        protected override void ClearItems()
        {
            base.ClearItems();
        }

        /// <summary>
        /// 设置指定索引处元素的值
        /// </summary>
        /// <param name="index"></param>
        /// <param name="item"></param>
        protected override void SetItem(int index, object item)
        {
            base.SetItem(index, item);
        }

        #endregion

        #region Items操作

        /// <summary>
        /// 
        /// </summary>
        /// <param name="index"></param>
        /// <param name="item"></param>
        protected void SetItem(int index, Entity item)
        {
            var entity = (Entity)Items[index];
            if (item == entity)
                return;

            OnItemRemoving(index, entity);
            OnItemAdding(index, item);
            //TODO: SetItem
            OnItemRemoved(index, entity);
            OnItemAdded(index, item);
        }

        /// <summary>
        /// 项目移除前
        /// </summary>
        /// <param name="index"></param>
        /// <param name="item"></param>
        private void OnItemRemoving(int index, Entity item)
        {

        }

        /// <summary>
        /// 项目移除后
        /// </summary>
        /// <param name="index"></param>
        /// <param name="item"></param>
        private void OnItemRemoved(int index, Entity item)
        {

        }

        /// <summary>
        /// 项目添加前
        /// </summary>
        /// <param name="index"></param>
        /// <param name="item"></param>
        private void OnItemAdding(int index, Entity item)
        {

        }

        /// <summary>
        /// 项目添加后
        /// </summary>
        /// <param name="index"></param>
        /// <param name="item"></param>
        private void OnItemAdded(int index, Entity item)
        {

        }

        /// <summary>
        /// 把指定的实体集合都回到本集合中来
        /// </summary>
        /// <param name="list"></param>
        public void AddRange(IEnumerable<Entity> list)
        {
            foreach (var entity in list)
                this.Add(entity);
        }

        #endregion
    }
}
